package com.ruoyi.websocker;


import com.alibaba.fastjson.JSON;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.socket.config.annotation.EnableWebSocket;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint("/websocket/{id}/{identity}")
@EnableWebSocket
@Slf4j

public class websocket {
    //用本地线程保存session
    private static ThreadLocal<Session> sessions = new ThreadLocal<Session>();
    //保存所有连接上的用户的session
    private static Map<String, SocketUserBean> userSessionMap = new ConcurrentHashMap<>();
    //保存在线客服的session
    private static Map<String, SocketUserBean> serverSessionMap = new ConcurrentHashMap<>();
    private final Object lock = new Object();

    //连接
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "identity") String role, @PathParam(value = "id") String id) {

        //默认返回错误状态
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("state", "error");
        //保证各个线程里的变量相对独立于其他线程内的变量
        sessions.set(session);
        //客服上线
        if (role.equals("客服")) {
            for (SocketUserBean socketUserBean : serverSessionMap.values()) {
                if (socketUserBean.getId().equals(id)) {
                    serverSessionMap.get(id).setSession(session);

                    System.out.println("替换成功");
                    System.out.println(serverSessionMap.get(id)+"1");
                    MessageBean messageBean=new MessageBean();
                    messageBean.setId(id);
                    messageBean.setRole("客服已重置");
                    messageBean.setMsg(socketUserBean.getUserId().toString());
                    messageBean.setTargetId(null);
                    sendMsg(serverSessionMap.get(id).getSession(),JSON.toJSONString(messageBean));
                    return;
                }
            }
            //创建一个在线客服信息
            SocketUserBean serverInfo = new SocketUserBean();
            serverInfo.setId(id);
            serverInfo.setSession(session);
            serverInfo.setUserRole("客服");
            serverSessionMap.put(id, serverInfo);
            //告诉客服连接成功
            resultMap.put("state", "success");
            for (SocketUserBean socketUserBean : userSessionMap.values()) {
                boolean result = false;
                System.out.println(userSessionMap.size() + "用户人数:" + socketUserBean.getId()+"2");
                if (socketUserBean.getTargetid() == "" || socketUserBean.getTargetid() == null) {
                    synchronized (lock) {
                        for (SocketUserBean V : serverSessionMap.values()) {
                            if (V.getUserId().size() == 0) {
                                System.out.println("size" + V.getUserId().size() + "key" + V.getId()+"3");
                                userSessionMap.get(socketUserBean.getId()).setTargetid(id);
                                V.getUserId().add(socketUserBean.getId());
                                System.out.println("用户" + userSessionMap.get(socketUserBean.getId()).getId() + "和" + V.getId() + "连上"+"4");
                                result = true;
                                MessageBean messageBean=new MessageBean();
                                messageBean.setMsg("客服连接成功");
                                messageBean.setTargetId(V.getId());
                                String msg=JSON.toJSONString(messageBean);
                                MessageBean messageBean1=new MessageBean();
                                messageBean1.setMsg("用户已连接");
                                messageBean1.setId(id);
                                messageBean1.setRole("客服");
                                messageBean1.setTargetId(socketUserBean.getId());
                                sendMsg(V.getSession(),JSON.toJSONString(messageBean1));
//                    String msg="当前工号为"+serverSessionMap.get(key).getId()+"正在为您服务";
                               // String msg="当前工号为"+V.getId()+"正在为您服务";
                                sendMsg(socketUserBean.getSession(),msg);
                                break;
                            }
                        }
                        if (result == false) {
                            int minSize = Integer.MAX_VALUE;
                            String key = null;
                            for (SocketUserBean V1 : serverSessionMap.values()) {
                                if (V1.getUserId().size() < minSize) {
                                    minSize = V1.getUserId().size();
                                    key = V1.getId();
                                    System.out.println("key" + key+"6");
                                }
                            }
                            serverSessionMap.get(key).getUserId().add(socketUserBean.getId());
                            userSessionMap.get(socketUserBean.getId()).setTargetid(id);

                            System.out.println("用户" + userSessionMap.get(socketUserBean.getId()).getId() + "和" + serverSessionMap.get(key) + "连上"+"7");
                            MessageBean messageBean=new MessageBean();
                            messageBean.setMsg("客服连接成功");
                            messageBean.setTargetId(serverSessionMap.get(key).getId());
                            String msg=JSON.toJSONString(messageBean);
                            MessageBean messageBean1=new MessageBean();
                            messageBean1.setMsg("用户已连接");
                            messageBean1.setRole("客服");
                            messageBean1.setId(id);
                            messageBean1.setTargetId(socketUserBean.getId());
                            sendMsg(serverSessionMap.get(id).getSession(),JSON.toJSONString(messageBean1));
                           // String msg="当前工号为"+ serverSessionMap.get(key).getId()+"正在为您服务";
                            sendMsg(socketUserBean.getSession(),msg);
                        }
                    }
                }
                //将在线客服信息保存到map中
                System.out.println("客服：" + serverInfo.getId() + "连接上服务器，当前在线客服共计：" + serverSessionMap.size()+"8");
            }
        } else if (role.equals("用户")) {
            //创建一个在线用户信息
            SocketUserBean userInfo = new SocketUserBean();
            userInfo.setId(id);
            userInfo.setSession(session);
            userInfo.setUserRole("用户");
            //告诉用户连接成功
            resultMap.put("state", "success");
            //去查询是否有在线的客服
            //有空闲客服就将用户和客服绑定
            synchronized (lock) {
                if (serverSessionMap.size() == 0) {
                    //没有客服在线
                    System.out.println("没有客服在线");
                    userSessionMap.put(id, userInfo);
                    MessageBean messageBean=new MessageBean();

                    String msg="没有客服在线";
                    messageBean.setMsg(msg);
                    sendMsg(session,JSON.toJSONString(messageBean));

                } else {
                    for (SocketUserBean V : serverSessionMap.values()) {
                        if (V.getUserId().size() == 0) {
                            System.out.println("size" + V.getUserId().size() + "key" + V.getId()+"9");
                            userInfo.setTargetid(V.getId());
                            userSessionMap.put(id, userInfo);
                            V.getUserId().add(id);
                            System.out.println("用户" + userInfo.getId() + "和" + V.getId() + "连上"+"10");
                            MessageBean messageBean=new MessageBean();
                            messageBean.setMsg("客服连接成功");
                            messageBean.setTargetId(V.getId());
                            String msg=JSON.toJSONString(messageBean);
//                    String msg="当前工号为"+serverSessionMap.get(key).getId()+"正在为您服务";
                            sendMsg(session,msg);
                            MessageBean messageBean1=new MessageBean();
                            messageBean1.setTargetId(id);
                            messageBean1.setId(V.getId());
                            messageBean1.setMsg("用户已连接");
                            messageBean1.setRole("客服");
                            sendMsg(serverSessionMap.get(messageBean1.getId()).getSession(),JSON.toJSONString(messageBean1));

                            return;
                        }
                    }
                    int minSize = Integer.MAX_VALUE;
                    String key = null;
                    for (SocketUserBean V : serverSessionMap.values()) {
                        if (V.getUserId().size() < minSize) {
                            minSize = V.getUserId().size();
                            key = V.getId();
                            System.out.println("key" + key+"11");
                        }
                    }
                    serverSessionMap.get(key).getUserId().add(id);
                    userInfo.setTargetid(key);
                    userSessionMap.put(id, userInfo);
                    System.out.println("用户" + userInfo.getId() + "和" + serverSessionMap.get(key) + "连上"+"12");
                    MessageBean messageBean=new MessageBean();
                    messageBean.setMsg("客服连接成功");
                    messageBean.setTargetId(serverSessionMap.get(key).getId());
                    String msg=JSON.toJSONString(messageBean);
//                    String msg="当前工号为"+serverSessionMap.get(key).getId()+"正在为您服务";
                    sendMsg(session,msg);
                    MessageBean messageBean1=new MessageBean();
                    messageBean1.setRole("kefu");
                    messageBean1.setMsg("用户已连接");
                    messageBean1.setId(serverSessionMap.get(key).getId());
                    messageBean1.setTargetId(id);
                    sendMsg(serverSessionMap.get(key).getSession(),JSON.toJSONString(messageBean1));
                }
            }
        }

    }

    //关闭连接
    @OnClose
    public void onClose(Session session, @PathParam(value = "id") String id, @PathParam(value = "identity") String role) {
        System.out.println(id + "---" + role+"13");
        System.out.println(userSessionMap.size()+"14");
        if (role.equals("用户")) {
            boolean result = false;
            for (SocketUserBean socketUserBean : serverSessionMap.values()) {
                synchronized (lock) {
                    if (socketUserBean.getUserId().size() == 0) {
                        result = false;
                        continue;
                    } else {
                        for (int i = 0; i < socketUserBean.getUserId().size(); i++) {
                            if (socketUserBean.getUserId().get(i).equals(id)) {
                                serverSessionMap.get(socketUserBean.getId()).getUserId().remove(i);
                                System.out.println(socketUserBean+"15");
                                MessageBean messageBean=new MessageBean(serverSessionMap.get(socketUserBean.getId()).getId(),"用户已下线",id,null);
                                sendMsg(serverSessionMap.get(socketUserBean.getId()).getSession(),JSON.toJSONString(messageBean));
                                userSessionMap.remove(id);
                                result = true;
                                break;
                            } else {
                                result = false;
                            }
                        }
                    }
                }
            }
            if (result == false) {
                userSessionMap.remove(id);
            }
        }
        System.out.println(userSessionMap.size()+"16");
        for (SocketUserBean socketUserBean : serverSessionMap.values()) {
            System.out.println(socketUserBean + "关闭"+"17");
        }
    }


    @OnMessage
    public void onMessage(String message, Session session, @PathParam(value = "id") String id) {
        System.out.println("发的消息为"+message+"18");
        RocketMQTemplate rocketMQTemplate = SpringUtils.getBean(RocketMQTemplate.class);
        MessageBean messageBean = JSON.parseObject(message, MessageBean.class);
        if (messageBean.getMsg().equals("下班") && messageBean.getRole().equals("客服")) {
            SocketUserBean socketUserBean = new SocketUserBean();
            socketUserBean = serverSessionMap.get(id);
            if (socketUserBean.getUserId().size() == 0) {
                serverSessionMap.remove(id);
            } else {
                for (int i = 0; i < socketUserBean.getUserId().size(); i++) {
                    boolean result = false;
                    synchronized (lock) {
                        if (serverSessionMap.size() - 1 > 0) {
                            for (SocketUserBean V : serverSessionMap.values()) {
                                if (V.getUserId().size() == 0 && !V.getId().equals(id)) {
                                    userSessionMap.get(socketUserBean.getUserId().get(i)).setTargetid(V.getId());
                                    serverSessionMap.get(V.getId()).getUserId().add(socketUserBean.getUserId().get(i));
                                    System.out.println("19"+serverSessionMap.get(V.getId()));
                                    result = true;
                                    break;
                                }
                            }
                            if (result == false) {
                                int minSize = Integer.MAX_VALUE;
                                String key = null;
                                for (SocketUserBean V : serverSessionMap.values()) {
                                    if (V.getUserId().size() < minSize && !V.getId().equals(id)) {
                                        minSize = V.getUserId().size();
                                        key = V.getId();

                                    }
                                }
                                serverSessionMap.get(key).getUserId().add(socketUserBean.getUserId().get(i));
                                userSessionMap.get(socketUserBean.getUserId().get(i)).setTargetid(key);
                                System.out.println("20"+serverSessionMap.get(key));
                            }

                        } else {
                            //没有客服在线
                            System.out.println("当前没有在线客服");
                        }
                    }
                }
                serverSessionMap.remove(id);
                System.out.println("21"+serverSessionMap.size() + "客服人数");
            }
        } else {
            if (messageBean.getRole().equals("客服")) {
                SocketUserBean socketUserBean = serverSessionMap.get(messageBean.getId());
                SocketUserBean socketUserBean1=userSessionMap.get(messageBean.getTargetId());
                if (socketUserBean1==null){
                    sendMsg(socketUserBean.getSession(),"用户已下线");
                }else{
                    sendMsg(userSessionMap.get(messageBean.getTargetId()).getSession(), JSON.toJSONString(messageBean));
                    rocketMQTemplate.convertAndSend("broker-a", messageBean);
                }

            } else {
                SocketUserBean socketUserBean = new SocketUserBean();
                socketUserBean = userSessionMap.get(messageBean.getId());
                System.out.println(socketUserBean+"22");
                SocketUserBean socketUserBean1=serverSessionMap.get(socketUserBean.getTargetid());
                System.out.println(socketUserBean1+"23");
                if (socketUserBean1==null){

                    rocketMQTemplate.convertAndSend("broker-a", messageBean);
                }else {

                    sendMsg(serverSessionMap.get(socketUserBean.getTargetid()).getSession(), JSON.toJSONString(messageBean));
                    messageBean.setTargetId(socketUserBean.getTargetid());
                    String msg = messageBean.toString();
                    rocketMQTemplate.convertAndSend("broker-a", messageBean);
                }

            }
        }


    }


    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("发生异常!");
        throwable.printStackTrace();
    }


    //统一的发送消息方法
    private synchronized void sendMsg(Session session, String msg) {

        try {
            session.getBasicRemote().sendText(msg);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


}
